<?php

namespace FacadePattern;

/**
 * 外观模式的角色和职责
 * 1. 外观类(Facade)：对外提供统一接口，封装子系统的调用。
 * 2. 子系统类(Subsystem)：负责自身的业务逻辑处理，通常不会对外暴露。
 */

// 以封装数据库操作为例，实现一个外观模式

// 1. 定义实体类，表示用户的数据结构
class User
{
    private int $id;
    private string $name;

    /**
     * @param int $id
     * @param string $name
     */
    public function __construct(int $id, string $name)
    {
        $this->id = $id;
        $this->name = $name;
    }

    /**
     * @return int
     */
    public function getId(): int
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }
}

// 2. 定义底层 DAO 接口和实现:封装原始数据库操作(模拟实现)
interface UserDAO
{
    public function insert(User $user): void;
    public function delete(int $id): void;
    public function update(User $user): void;
    public function findById(int $id): User;
}

// 实现DAO接口
class UserDaoImpl implements UserDAO
{
    public function insert(User $user): void
    {
        // 模拟一系列的数据库操作
        echo "插入用户：{$user->getName()}\n";
    }

    public function delete(int $id): void
    {
        // 模拟一系列的数据库操作
        echo "删除用户：{$id}\n";
    }
    public function update(User $user): void
    {
        // 模拟一系列的数据库操作
        echo "更新用户：{$user->getName()}\n";
    }
    public function findById(int $id): User
    {
        // 模拟一系列的数据库操作
        echo "查询用户：{$id}\n";
        return new User($id, '张三');
    }
}

// 外观类，对外提供接口
class UserServiceFacade
{
    private UserDao $userDAO;

    public function __construct()
    {
        $this->userDAO = new UserDaoImpl();
    }

    /**
     * Notes: 对外提供创建用户接口
     * User: lhz
     * DateTime: 2025/7/17 0:51
     * @param int $id
     * @param string $name
     * @return void
     */
    public function createUser(int $id, string $name): User
    {
        $user = new User($id, $name);
        $this->userDAO->insert($user);
        return $user;
    }

    /**
     * Notes: 对外提供查询用户接口
     * User: lhz
     * DateTime: 2025/7/17 0:51
     * @param int $id
     * @return User
     */
    public function viewUser(int $id): User
    {
        return $this->userDAO->findById($id);
    }

    /**
     * Notes: 对外提供修改用户信息接口
     * User: lhz
     * DateTime: 2025/7/17 0:53
     * @param User $user
     * @return void
     */
    public function updateUser(User $user): void
    {
        $this->userDAO->update($user);
    }

    /**
     * Notes: 对外提供删除用户接口
     * User: lhz
     * DateTime: 2025/7/17 0:53
     * @param int $id
     * @return void
     */
    public function removeUser(int $id): void
    {
        $this->userDAO->delete($id);
    }
}

// 测试
$userServiceFacade = new UserServiceFacade();
$user = $userServiceFacade->createUser(1, 'azhen');
$userServiceFacade->removeUser($user->getId());
$userServiceFacade->updateUser($user);
$userServiceFacade->viewUser($user->getId());